package com.legal.aop;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import org.springframework.util.StopWatch;

/**
 * @author xiaopeng
 * @version 1.0
 */
@Slf4j
@Aspect
@Component
public class MethodExecutionTimeAspect {

    /**
     * 定义切点：监控所有Service层和Controller层方法
     * 可根据需要调整包路径
     */
    @Pointcut("execution(* com.legal.service..*.*(..)) || " +
            "execution(* com.legal.controller..*.*(..))")
    public void monitorMethod() {}

    /**
     * 环绕通知：计算方法执行耗时
     */
    @Around("monitorMethod()")
    public Object logExecutionTime(ProceedingJoinPoint joinPoint) throws Throwable {
        StopWatch stopWatch = new StopWatch();

        try {
            stopWatch.start();
            // 执行目标方法
            return joinPoint.proceed();
        } finally {
            stopWatch.stop();

            // 获取方法信息
            String className = joinPoint.getTarget().getClass().getSimpleName();
            String methodName = joinPoint.getSignature().getName();
            long executionTime = stopWatch.getTotalTimeMillis();

            // 根据耗时级别记录日志
            if (executionTime > 1000) {
                log.warn("[性能警告] {}.{} 执行耗时: {} ms", className, methodName, executionTime);
            } else if (executionTime > 500) {
                log.info("[性能提示] {}.{} 执行耗时: {} ms", className, methodName, executionTime);
            } else {
                log.debug("[方法追踪] {}.{} 执行耗时: {} ms", className, methodName, executionTime);
            }
        }
    }
}